#include "device.h"
#include "component.h"

/* 调试打印接口 */
#define BEEP_LOG(format, ...)  __OSAL_LOG("[beep.c] " C_GREEN format C_NONE, ##__VA_ARGS__)

/* 蜂鸣器响事件 */
#define EVENT_BEEP_RING     ( 0X00000001 )

/* 蜂鸣器响的事件处理周期 */
#define BEEP_RING_EVT_PROC_CYCLE  (10)

#define BEEP_PWM_VHW        vPWM_0  //定义虚拟硬件

static BeepNv_stu_t BeepVoiceInfo;// 默认有声音   蜂鸣器的声音
static struct
{
    uint8_t count;  				//计数
    uint8_t times;  				//鸣叫总次数：0XFF表示永久鸣叫
    uint32_t cycle; 				//鸣叫周期
    uint32_t timestamp;				//计时
}beepRing;

/**
  * @brief  处理蜂鸣器鸣叫事件
  *         
  * @note   该事件100ms执行一次
  */
static void Beep_ProcessRingEvent(void)
{
    if (beepRing.times == 0)
    {
        return;
    }

    uint32_t time = OSAL_GetTickCount();
    if (OSAL_PastTime(time, beepRing.timestamp) >= beepRing.cycle || beepRing.count == 0)
    {
        beepRing.timestamp = time;
        if ((++beepRing.count < beepRing.times) || (beepRing.times == 0xFF))
        {
            /* 蜂鸣器的发声频率是4K，20%的占空比 */
            (beepRing.count & 1) ? (Device_Enable(BEEP_PWM_VHW), Device_SetPwm(BEEP_PWM_VHW, 4000, 20)) : Device_Disable(BEEP_PWM_VHW);
        }
        else
        {
            beepRing.times = 0;
            Device_Disable(BEEP_PWM_VHW);
            OSAL_EventDelete(COMP_BEEP, EVENT_BEEP_RING);

            OSAL_SetTaskStatus(TASK_STA_NORMAL);
        }
    }
}

/**
  * @brief  控制蜂鸣器接口
  *         
  * @param  times：鸣叫总次数：0XFF表示永久鸣叫
  * @param  cycle：鸣叫周期
  * @note   当times或者cycle有一项为0时则关闭蜂鸣器
  */
static ErrorStatus Beep_SetApi(uint32_t cycle, uint8_t times)
{
	BEEP_LOG("Beep_SetApi times = %d, cycle = %ld\r\n", times, cycle);

    if (times == 0 || cycle == 0)
    {
        return ERROR;
    }
    else
    {
        /* 暂存蜂鸣器闪烁数据 */
        beepRing.count = 0;
        beepRing.times = times * 2;
        beepRing.cycle = cycle;
        OSAL_EventRepeatCreate(COMP_BEEP, EVENT_BEEP_RING, BEEP_RING_EVT_PROC_CYCLE, EVT_PRIORITY_MEDIUM);

        /* 立即执行一次蜂鸣器事件 */
        Beep_ProcessRingEvent();

        OSAL_SetTaskStatus(TASK_STA_ACTIVE);
    }
    return SUCCESS;
}
/**
 * @brief 0 设置静音/非静音模式 1
 * 
 * @param mode 
 */
static void Beep_SetMuteModeApi(uint8_t mode)
{
    BeepVoiceInfo.mute = mode;
    BEEP_LOG("BeepVoiceInfo.mute:%d\r\n",BeepVoiceInfo.mute);
    OSAL_NvWrite(0, &BeepVoiceInfo, sizeof(BeepNv_stu_t));
}
/**
 * @brief NV初始化
 * 
 */
static void Beep_NvInit(void)
{
    BeepNv_stu_t tmp;
    memset(&tmp,0,sizeof(BeepNv_stu_t));
    OSAL_NvRead(0, &tmp, sizeof(BeepNv_stu_t));
    if(tmp.nvInitFlag != BEEP_NV_INIT_FLAG)
    {
        BEEP_LOG("Beep Nv Reset\r\n");
        tmp.nvInitFlag = BEEP_NV_INIT_FLAG;
        tmp.mute= 1;//语音模式
        OSAL_NvWrite(0, &tmp, sizeof(tmp));
    }
    OSAL_NvRead(0, &BeepVoiceInfo, sizeof(BeepNv_stu_t));
    BEEP_LOG("BeepVoiceInfo.mute:%d\r\n",BeepVoiceInfo.mute);
}



/**
  * @brief  Beep任务函数
  *
  * @note   1.任务函数内不能写阻塞代码
  *         2.任务函数每次运行只处理一个事件
  *         
  * @param  event：当前任务的所有事件
  *
  * @return 返回未处理的事件
  */
static uint32_t Beep_Task(uint32_t event)
{
	/* 系统启动事件 */
	if (event & EVENT_SYS_START)
	{
		BEEP_LOG("Beep task start\r\n");
        Beep_NvInit();
		return ( event ^ EVENT_SYS_START );
	}

    if (event & EVENT_SYS_MBOX)
    {
        uint8_t temp[4] = {0};
        while (OSAL_MboxAccept(temp))
        {
            switch(temp[0])
            {
                case BEEP_MBOX_VOICE_CONTROL:
                if(BeepVoiceInfo.mute !=0) Beep_SetApi(*(uint16_t *)(&temp[1]), temp[3]);
                break;
                case BEEP_MBOX_MUTE_CONTROL:
                Beep_SetMuteModeApi(temp[1]); break;
                default:
                break;
            }
        }
        return ( event ^ EVENT_SYS_MBOX );
    }
	
	/* 系统休眠事件 */
	if (event & EVENT_SYS_SLEEP)
	{
        OSAL_EventDelete(COMP_BEEP, EVENT_BEEP_RING);
		return ( event ^ EVENT_SYS_SLEEP );
    }
	
	/* 蜂鸣器响事件 */
	if (event & EVENT_BEEP_RING)
	{
        Beep_ProcessRingEvent();
		return ( event ^ EVENT_BEEP_RING );
	}
	return 0;
}
COMPONENT_TASK_EXPORT(COMP_BEEP, Beep_Task, sizeof(BeepNv_stu_t));
